home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / shelly14.lha / shelly / shelly.c < prev    next >
C/C++ Source or Header  |  1994-04-25  |  31KB  |  1,293 lines

  1. /*****************************************************/
  2. /* ShellyV1.4: The ShellShapeGenerator by:           */
  3. /*         RANDi                                     */
  4. /*              (rschultz@informatik.uni-rostock.de) */
  5. /*****************************************************/
  6.  
  7. #include <math.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <memory.h>
  12.  
  13. #include "shelly.h"
  14.  
  15. int countw = 0, counth = 0, countp = 0;
  16. double camx = 0, camy = 500, camz = 500;
  17.  
  18. /********************************************/
  19. /*cot:                                      */
  20. /********************************************/
  21. double
  22. cot (double in)
  23. {
  24.   if (sin (in) == 0)
  25.     return (0);
  26.   else
  27.     return (cos (in) / sin (in));
  28. }
  29.  
  30.  
  31. /********************************************/
  32. /*round:                                    */
  33. /********************************************/
  34. double
  35. round (double in)
  36. {
  37.   if (in - floor (in) < 0.5)
  38.     return (floor (in));
  39.   else
  40.     return (floor (in) + 1);
  41. }
  42.  
  43.  
  44. /********************************************/
  45. /*myfree:                                   */
  46. /********************************************/
  47. int
  48. myfree (struct punkt *anker1)
  49. {
  50.   struct punkt *hp, *hpnew;
  51.   if (anker1 == NULL)
  52.     return (0);
  53.  
  54.   hp = anker1;
  55.   hpnew = hp;
  56.   do
  57.     {
  58.       hp = hpnew;
  59.       hpnew = (*hp).next;
  60.  
  61.       free (hp);
  62.     }
  63.   while (hpnew != NULL);
  64.  
  65.   return (0);
  66. }
  67.  
  68.  
  69. /********************************************/
  70. /*mycopystr:                                */
  71. /********************************************/
  72. char *
  73. mycopystr (char *source, char *destination, char endchar)
  74. {
  75.   int ende = 1;
  76.   char *merk;
  77.  
  78.   merk = destination;        /* merk points now on destination */
  79.   while (ende)
  80.     {
  81.       if ((*source == '\0') || (*source == endchar))
  82.     {
  83.       ende = 0;
  84.     }
  85.       else
  86.     {
  87.       *destination = *source;
  88.       destination++;
  89.       source++;
  90.     }            /* if */
  91.     }                /* while */
  92.   *destination = '\0';
  93.   return (merk);
  94. }
  95.  
  96.  
  97. /********************************************/
  98. /*filecopy:                                 */
  99. /********************************************/
  100. void
  101. filecopy (FILE * source, FILE * dest)
  102. {
  103.   int a, b;
  104.  
  105.   fseek (source, 0, 0);
  106.   do
  107.     {
  108.       a = fgetc (source);
  109.       if (a != EOF)
  110.     {
  111.       b = fputc (a, dest);
  112.       if (b == EOF)
  113.         {
  114.           fclose (source);
  115.           fclose (dest);
  116.           exit (5);
  117.         };            /* if */
  118.     };            /* if */
  119.     }
  120.   while (a != EOF);
  121. }
  122.  
  123. /********************************************/
  124. /*ReadInfile:                               */
  125. /********************************************/
  126. void
  127. ReadInfile (struct ShellyArguments *ShellyArgs, char *fin)
  128. {
  129.   char readline[laenge], hilf[laenge], *hp;
  130.   FILE *fp;
  131.  
  132.   /* set some defaults */
  133.  
  134.   (*ShellyArgs).output = POV;
  135.   (*ShellyArgs).mode = NORMAL;
  136.   (*ShellyArgs).Scan = 0.2;
  137.   (*ShellyArgs).Threshold = 0.001;
  138.   (*ShellyArgs).Scale = 1.0;
  139.   (*ShellyArgs).Render = NO;
  140.   (*ShellyArgs).N2 = 0;
  141.   (*ShellyArgs).N3 = 0;
  142.   (*ShellyArgs).N = 0;
  143.  
  144.  
  145.   mycopystr ("-f +d +w200 +h160", (*ShellyArgs).povargs, '\0');
  146.  
  147.  
  148.   fp = fopen (fin, "r");
  149.   if (fp != NULL)
  150.     {
  151.       fprintf (stderr, "Parsing:");
  152.       while (fgets (readline, laenge, fp) != NULL)
  153.     {
  154.       fprintf (stderr, ".");
  155.  
  156.       hp = strstr (readline, "alpha:");
  157.       if (hp != NULL)
  158.         {
  159.           mycopystr (hp + 6, hilf, '\0');
  160.           (*ShellyArgs).alpha = atof (hilf);
  161.         }            /* if */
  162.       hp = strstr (readline, "beta:");
  163.       if (hp != NULL)
  164.         {
  165.           mycopystr (hp + 5, hilf, '\0');
  166.           (*ShellyArgs).beta = atof (hilf);
  167.         }            /* if */
  168.       hp = strstr (readline, "phi:");
  169.       if (hp != NULL)
  170.         {
  171.           mycopystr (hp + 4, hilf, '\0');
  172.           (*ShellyArgs).phi = atof (hilf);
  173.         }            /* if */
  174.       hp = strstr (readline, "my:");
  175.       if (hp != NULL)
  176.         {
  177.           mycopystr (hp + 3, hilf, '\0');
  178.           (*ShellyArgs).my = atof (hilf);
  179.         }            /* if */
  180.       hp = strstr (readline, "omega:");
  181.       if (hp != NULL)
  182.         {
  183.           mycopystr (hp + 6, hilf, '\0');
  184.           (*ShellyArgs).omega = atof (hilf);
  185.         }            /* if */
  186.       hp = strstr (readline, "smin:");
  187.       if (hp != NULL)
  188.         {
  189.           mycopystr (hp + 5, hilf, '\0');
  190.           (*ShellyArgs).smin = atof (hilf);
  191.         }            /* if */
  192.       hp = strstr (readline, "smax:");
  193.       if (hp != NULL)
  194.         {
  195.           mycopystr (hp + 5, hilf, '\0');
  196.           (*ShellyArgs).smax = atof (hilf);
  197.         }            /* if */
  198.       hp = strstr (readline, "sd:");
  199.       if (hp != NULL)
  200.         {
  201.           mycopystr (hp + 3, hilf, '\0');
  202.           (*ShellyArgs).sd = atof (hilf);
  203.         }            /* if */
  204.       hp = strstr (readline, "A:");
  205.       if (hp != NULL)
  206.         {
  207.           mycopystr (hp + 2, hilf, '\0');
  208.           (*ShellyArgs).A = atof (hilf);
  209.         }            /* if */
  210.       hp = strstr (readline, "a:");
  211.       if (hp != NULL)
  212.         {
  213.           mycopystr (hp + 2, hilf, '\0');
  214.           (*ShellyArgs).a = atof (hilf);
  215.         }            /* if */
  216.       hp = strstr (readline, "b:");
  217.       if (hp != NULL)
  218.         {
  219.           mycopystr (hp + 2, hilf, '\0');
  220.           (*ShellyArgs).b = atof (hilf);
  221.         }            /* if */
  222.       hp = strstr (readline, "P:");
  223.       if (hp != NULL)
  224.         {
  225.           mycopystr (hp + 2, hilf, '\0');
  226.           (*ShellyArgs).P = atof (hilf);
  227.         }            /* if */
  228.       hp = strstr (readline, "W1:");
  229.       if (hp != NULL)
  230.         {
  231.           mycopystr (hp + 3, hilf, '\0');
  232.           (*ShellyArgs).W1 = atof (hilf);
  233.         }            /* if */
  234.       hp = strstr (readline, "W2:");
  235.       if (hp != NULL)
  236.         {
  237.           mycopystr (hp + 3, hilf, '\0');
  238.           (*ShellyArgs).W2 = atof (hilf);
  239.         }            /* if */
  240.       hp = strstr (readline, "N:");
  241.       if (hp != NULL)
  242.         {
  243.           mycopystr (hp + 2, hilf, '\0');
  244.           (*ShellyArgs).N = atof (hilf);
  245.         }            /* if */
  246.       hp = strstr (readline, "L:");
  247.       if (hp != NULL)
  248.         {
  249.           mycopystr (hp + 2, hilf, '\0');
  250.           (*ShellyArgs).L = atof (hilf);
  251.         }            /* if */
  252.       hp = strstr (readline, "omin:");
  253.       if (hp != NULL)
  254.         {
  255.           mycopystr (hp + 5, hilf, '\0');
  256.           (*ShellyArgs).omin = atof (hilf);
  257.         }            /* if */
  258.       hp = strstr (readline, "omax:");
  259.       if (hp != NULL)
  260.         {
  261.           mycopystr (hp + 5, hilf, '\0');
  262.           (*ShellyArgs).omax = atof (hilf);
  263.         }            /* if */
  264.       hp = strstr (readline, "od:");
  265.       if (hp != NULL)
  266.         {
  267.           mycopystr (hp + 3, hilf, '\0');
  268.           (*ShellyArgs).od = atof (hilf);
  269.         }            /* if */
  270.       hp = strstr (readline, "o2d:");
  271.       if (hp != NULL)
  272.         {
  273.           mycopystr (hp + 4, hilf, '\0');
  274.           (*ShellyArgs).nod = atof (hilf);
  275.         }            /* if */
  276.       hp = strstr (readline, "Threshold:");
  277.       if (hp != NULL)
  278.         {
  279.           mycopystr (hp + 10, hilf, '\0');
  280.           (*ShellyArgs).Threshold = atof (hilf);
  281.         }            /* if */
  282.       hp = strstr (readline, "Scan:");
  283.       if (hp != NULL)
  284.         {
  285.           mycopystr (hp + 5, hilf, '\0');
  286.           (*ShellyArgs).Scan = atof (hilf);
  287.         }            /* if */
  288.  
  289.       hp = strstr (readline, "Scale:");
  290.       if (hp != NULL)
  291.         {
  292.           mycopystr (hp + 6, hilf, '\0');
  293.           (*ShellyArgs).Scale = atof (hilf);
  294.         }            /* if */
  295.  
  296.       hp = strstr (readline, "POV");
  297.       if (hp != NULL)
  298.         {
  299.           (*ShellyArgs).output = POV;
  300.         }            /* if */
  301.       hp = strstr (readline, "RPL");
  302.       if (hp != NULL)
  303.         {
  304.           (*ShellyArgs).output = RPL;
  305.         }            /* if */
  306.       hp = strstr (readline, "T3D");
  307.       if (hp != NULL)
  308.         {
  309.           (*ShellyArgs).output = T3D;
  310.         }            /* if */
  311.       hp = strstr (readline, "RAW");
  312.       if (hp != NULL)
  313.         {
  314.           (*ShellyArgs).output = RAW;
  315.         }            /* if */
  316.  
  317.       hp = strstr (readline, "NORMAL");
  318.       if (hp != NULL)
  319.         {
  320.           (*ShellyArgs).mode = NORMAL;
  321.         }            /* if */
  322.       hp = strstr (readline, "NODULE");
  323.       if (hp != NULL)
  324.         {
  325.           (*ShellyArgs).mode = NODULE;
  326.         }            /* if */
  327.       hp = strstr (readline, "RENDER");
  328.       if (hp != NULL)
  329.         {
  330.           (*ShellyArgs).Render = YES;
  331.         }            /* if */
  332.  
  333.       hp = strstr (readline, "POVARGS:");
  334.       if (hp != NULL)
  335.         mycopystr (hp + 8, (*ShellyArgs).povargs, '\n');
  336.  
  337.       hp = strstr (readline, "P2:");
  338.       if (hp != NULL)
  339.         {
  340.           mycopystr (hp + 3, hilf, '\0');
  341.           (*ShellyArgs).P2 = atof (hilf);
  342.         }            /* if */
  343.       hp = strstr (readline, "W12:");
  344.       if (hp != NULL)
  345.         {
  346.           mycopystr (hp + 4, hilf, '\0');
  347.           (*ShellyArgs).W12 = atof (hilf);
  348.         }            /* if */
  349.       hp = strstr (readline, "W22:");
  350.       if (hp != NULL)
  351.         {
  352.           mycopystr (hp + 4, hilf, '\0');
  353.           (*ShellyArgs).W22 = atof (hilf);
  354.         }            /* if */
  355.       hp = strstr (readline, "N2:");
  356.       if (hp != NULL)
  357.         {
  358.           mycopystr (hp + 3, hilf, '\0');
  359.           (*ShellyArgs).N2 = atof (hilf);
  360.         }            /* if */
  361.       hp = strstr (readline, "L2:");
  362.       if (hp != NULL)
  363.         {
  364.           mycopystr (hp + 3, hilf, '\0');
  365.           (*ShellyArgs).L2 = atof (hilf);
  366.         }            /* if */
  367.       hp = strstr (readline, "P3:");
  368.       if (hp != NULL)
  369.         {
  370.           mycopystr (hp + 3, hilf, '\0');
  371.           (*ShellyArgs).P3 = atof (hilf);
  372.         }            /* if */
  373.       hp = strstr (readline, "W13:");
  374.       if (hp != NULL)
  375.         {
  376.           mycopystr (hp + 4, hilf, '\0');
  377.           (*ShellyArgs).W13 = atof (hilf);
  378.         }            /* if */
  379.       hp = strstr (readline, "W23:");
  380.       if (hp != NULL)
  381.         {
  382.           mycopystr (hp + 4, hilf, '\0');
  383.           (*ShellyArgs).W23 = atof (hilf);
  384.         }            /* if */
  385.       hp = strstr (readline, "N3:");
  386.       if (hp != NULL)
  387.         {
  388.           mycopystr (hp + 3, hilf, '\0');
  389.           (*ShellyArgs).N3 = atof (hilf);
  390.         }            /* if */
  391.       hp = strstr (readline, "L3:");
  392.       if (hp != NULL)
  393.         {
  394.           mycopystr (hp + 3, hilf, '\0');
  395.           (*ShellyArgs).L3 = atof (hilf);
  396.         }            /* if */
  397.       hp = strstr (readline, "Off2:");
  398.       if (hp != NULL)
  399.         {
  400.           mycopystr (hp + 5, hilf, '\0');
  401.           (*ShellyArgs).Off2 = atof (hilf);
  402.         }            /* if */
  403.       hp = strstr (readline, "Off3:");
  404.       if (hp != NULL)
  405.         {
  406.           mycopystr (hp + 5, hilf, '\0');
  407.           (*ShellyArgs).Off3 = atof (hilf);
  408.         }            /* if */
  409.  
  410.     }            /* while */
  411.  
  412.       fprintf (stderr, "\n");
  413.       if (fclose (fp) != 0)
  414.     fprintf (stderr, "Error while closing file: %s!\n", fin);
  415.     }
  416.   else
  417.     {
  418.       fprintf (stderr, "Could not open datafile: %s!\n", fin);
  419.       exit (5);
  420.     }
  421. }                /* ReadInfile */
  422.  
  423.  
  424. /********************************************/
  425. /* writepovheader:                          */
  426. /*                                          */
  427. /********************************************/
  428. void
  429. writepovheader (FILE * fp)
  430. {
  431.  
  432.   fprintf (fp, "/* POV-Scenefile generated by Shelly1.4           */\n");
  433.   fprintf (fp, "/* by RANDi: (rschultz@informatik.uni-rostock.de) */\n");
  434.  
  435.   fprintf (fp, "#declare te = pigment { color red 1 green 0 blue 0 }\n");
  436.  
  437.   fprintf (fp, "camera\n{\n location  <%.1f,%.1f,%.1f>\n", camx, camy, camz);
  438.   fprintf (fp, " look_at <0, 0, 0>\n}\n");
  439.  
  440.   fprintf (fp, "object\n{\n light_source {\n");
  441.   fprintf (fp, "  <250, 500, 500> color red 1 green 1 blue 1\n }\n");
  442.   fprintf (fp, "}\n");
  443.   fprintf (fp, "object\n{\n light_source {\n");
  444.   fprintf (fp, "  <-250, 500, 500> color red 1 green 1 blue 1\n }\n");
  445.   fprintf (fp, "}\n");
  446.  
  447. }                /* writepovheader */
  448.  
  449.  
  450. /********************************************/
  451. /* writepovtriangles:                       */
  452. /********************************************/
  453. int
  454. writepovtriangles (FILE * fp, struct punkt *anker1, struct punkt *anker2)
  455. {
  456.   struct punkt *p11, *p12, *p21, *p22;
  457.  
  458.   if ((anker1 == NULL) || (anker2 == NULL))
  459.     return (0);
  460.  
  461.   p11 = anker1;
  462.   p12 = p11;
  463.   p21 = anker2;
  464.   p22 = p21;
  465.  
  466.   do
  467.     {
  468.       p11 = p12;
  469.       p21 = p22;
  470.       p12 = (*p11).next;
  471.       p22 = (*p21).next;
  472.  
  473.       if ((p12 != NULL) && (p22 != NULL))
  474.     {
  475.       fprintf (fp, "triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n", (*p11).x, (*p11).y, (*p11).z, (*p12).x, (*p12).y, (*p12).z, (*p21).x, (*p21).y, (*p21).z);
  476.       fprintf (fp, "pigment{te}}\n");
  477.  
  478.       fprintf (fp, "triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n", (*p21).x, (*p21).y, (*p21).z, (*p12).x, (*p12).y, (*p12).z, (*p22).x, (*p22).y, (*p22).z);
  479.       fprintf (fp, "pigment{te}}\n");
  480.     }
  481.     }
  482.   while ((p12 != NULL) && (p22 != NULL));
  483.  
  484.   return (0);
  485. }                /* writepovtriangles */
  486.  
  487.  
  488. /********************************************/
  489. /* writepovfinish:                          */
  490. /********************************************/
  491. void
  492. writepovfinish (FILE * fptemp, FILE * fp)
  493. {
  494.  
  495.   filecopy (fptemp, fp);
  496.  
  497. }
  498.  
  499.  
  500. /********************************************/
  501. /* writerplline:                            */
  502. /********************************************/
  503. int
  504. writerplline (FILE * fp, struct punkt *anker1)
  505. {
  506.   struct punkt *p11, *p12;
  507.  
  508.   if (anker1 == NULL)
  509.     return (0);
  510.  
  511.   p11 = anker1;
  512.   p12 = p11;
  513.  
  514.   countw++;            /* calc number of lines created */
  515.  
  516.   fprintf (fp, "%.3f  %.3f  %.3f\n", (*p11).x / 100.0, (*p11).y / 100.0, (*p11).z / 100.0);
  517.  
  518.   do
  519.     {
  520.       p11 = p12;
  521.       p12 = (*p11).next;
  522.  
  523.       if (p12 != NULL)
  524.     {
  525.       fprintf (fp, "%.3f  %.3f  %.3f\n", (*p12).x / 100.0, (*p12).y / 100.0, (*p12).z / 100.0);
  526.     }
  527.     }
  528.   while (p12 != NULL);
  529.  
  530.   return (0);
  531. }                /* writerplline */
  532.  
  533.  
  534. /********************************************/
  535. /* writerplfinish:                          */
  536. /*                                          */
  537. /********************************************/
  538. void
  539. writerplfinish (FILE * fptemp, FILE * fp)
  540. {
  541.  
  542.   filecopy (fptemp, fp);
  543.  
  544.   fprintf (fp, "%d\n", counth);    /* height width of the mesh */
  545.   fprintf (fp, "%d\n", countw);
  546.  
  547.   fprintf (fp, "3\n0\n255 255 255 0\n");    /* RGBA */
  548.   fprintf (fp, "\"Shell\"\n0\n");    /* Name */
  549.   fprintf (fp, "\"CEND\"\n");
  550.   fprintf (fp, "C_MESH DROP\n");
  551.  
  552. }                /* writerplfinish */
  553.  
  554.  
  555. /********************************************/
  556. /* writet3dheader:                          */
  557. /*                                          */
  558. /********************************************/
  559. void
  560. writet3dheader (FILE * fp)
  561. {
  562.   char percent = '%';
  563.  
  564.   fprintf (fp, " %c T3Dlib-data-file generated by Shelly1.4\n", percent);
  565.   fprintf (fp, " %c the ShellShapeGenerator by RANDi :    \n", percent);
  566.   fprintf (fp, " %c (rschultz@informatik.uni-rostock.de)\n", percent);
  567.  
  568.   fprintf (fp, "OBJ Begin \"Hierarchy 1\"\n");
  569.   fprintf (fp, " DESC Begin \"Object 1 at level 1 of hierarchy 1\"\n");
  570.   fprintf (fp, "  NAME \"SHELL\"\n");
  571.   fprintf (fp, "  SHAP Shape = 2\n");
  572.   fprintf (fp, "  SHAP Lamp  = 0\n");
  573.   fprintf (fp, "  POSI X=0 Y=0 Z=0\n");
  574.   fprintf (fp, "  AXIS XAxis X=1 Y=0 Z=0\n");
  575.   fprintf (fp, "  AXIS YAxis X=0 Y=1 Z=0\n");
  576.   fprintf (fp, "  AXIS ZAxis X=0 Y=0 Z=1\n");
  577.   fprintf (fp, "  SIZE X=32 Y=32 Z=32\n");
  578.  
  579. }                /* writet3dheader */
  580.  
  581.  
  582. /********************************************/
  583. /* writet3dline:                            */
  584. /********************************************/
  585. int
  586. writet3dline (FILE * fp, struct punkt *anker1)
  587. {
  588.   struct punkt *p11, *p12;
  589.  
  590.   static int called = 0, count = 0;
  591.   if (anker1 == NULL)
  592.     return (0);
  593.  
  594.   if (called == 0)
  595.     {
  596.       called = 1;
  597.       count = -1;
  598.       countw = 0;
  599.     }
  600.   countw++;
  601.  
  602.   p11 = anker1;
  603.   p12 = p11;
  604.  
  605.   fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", ++count, (*p11).x, (*p11).y, (*p11).z);
  606.  
  607.   do
  608.     {
  609.       p11 = p12;
  610.       p12 = (*p11).next;
  611.  
  612.       if (p12 != NULL)
  613.     {
  614.       fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", ++count, (*p12).x, (*p12).y, (*p12).z);
  615.     }
  616.     }
  617.   while (p12 != NULL);
  618.  
  619.   return (0);
  620. }                /* writet3dline */
  621.  
  622.  
  623. /********************************************/
  624. /* writet3dfinish:                          */
  625. /*                                          */
  626. /********************************************/
  627. void
  628. writet3dfinish (FILE * fptemp, FILE * fp)
  629. {
  630.   int edges = 0, faces = 0, edgecount = 0, facecount = 0, a = 0, b = 0,
  631.     r = 0, r2 = 0, r3 = 0;
  632.   int point1 = 0, point2 = 0, edge1 = 0, edge2 = 0, edge3 = 0;
  633.  
  634.  
  635.   fprintf (stderr, "\nWriting additional T3Dlib-Data ...");
  636.  
  637.   fprintf (fp, "  PNTS PCount %d\n", countp);
  638.  
  639.   filecopy (fptemp, fp);
  640.  
  641.  
  642.   edges = (counth * (countw - 1) + countw * (counth - 1) + (counth - 1) * (countw - 1));
  643.   /* number of edges! */
  644.   fprintf (fp, "  EDGE ECount %d\n", edges);
  645.  
  646.  
  647.   /* write horizontal edges */
  648.   for (a = 0; a < counth; a++)
  649.     {
  650.       r = a;
  651.       for (b = 0; b < (countw - 1); b++)
  652.     {
  653.       point1 = r;
  654.       point2 = r + counth;
  655.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  656.       r = r + counth;
  657.     }
  658.     }
  659.   /* write vertical edges */
  660.   for (a = 0; a < countw; a++)
  661.     {
  662.       r = a * counth;
  663.       for (b = 0; b < (counth - 1); b++)
  664.     {
  665.       point1 = r + b;
  666.       point2 = r + b + 1;
  667.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  668.     }
  669.     }
  670.   /* write diagonal edges */
  671.   for (a = 0; a < counth - 1; a++)
  672.     {
  673.       r = a;
  674.       for (b = 0; b < (countw - 1); b++)
  675.     {
  676.       point1 = r;
  677.       point2 = r + counth + 1;
  678.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  679.       r = r + counth;
  680.     }
  681.     }
  682.   /* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */
  683.  
  684.   /* write faces */
  685.  
  686.   faces = 2 * (countw - 1) * (counth - 1);
  687.  
  688.   fprintf (fp, "  FACE TCount %d\n", faces);
  689.  
  690.   r = 0;
  691.   r3 = countw * (counth - 1) + counth * (countw - 1);
  692.  
  693.   for (a = 0; a < counth - 1; a++)
  694.     {
  695.       r2 = counth * (countw - 1) + a;
  696.       for (b = 0; b < countw - 1; b++)
  697.     {
  698.       edge1 = r + countw - 1;
  699.       edge2 = r2;
  700.       edge3 = r3;
  701.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, edge1, edge2, edge3);
  702.  
  703.       edge1 = r;
  704.       edge2 = r2 + counth - 1;
  705.       edge3 = r3;
  706.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, edge1, edge2, edge3);
  707.  
  708.       r++;
  709.       r2 = r2 + counth - 1;
  710.       r3++;
  711.     }
  712.     }
  713.  
  714.   fprintf (fp, "  COLR R=98 G=68 B=58\n");
  715.   fprintf (fp, "  REFL R=0 G=0 B=0\n");
  716.   fprintf (fp, "  TRAN R=0 G=0 B=0\n");
  717.   fprintf (fp, "  SPC1 R=0 G=0 B=0\n");
  718.   fprintf (fp, "  End DESC   \"Object 1 at level 1 of hierarchy 1\"\n");
  719.   fprintf (fp, " TOBJ       \"Object 0 at level 1 of hierarchy 1\"\n");
  720.   fprintf (fp, "End OBJ  \"Hierarchy 1\"\n");
  721.  
  722. }                /* writet3dfinish */
  723.  
  724.  
  725. /********************************************/
  726. /* writerawtriangles:                       */
  727. /********************************************/
  728. int
  729. writerawtriangles (FILE * fp, struct punkt *anker1, struct punkt *anker2)
  730. {
  731.   struct punkt *p11, *p12, *p21, *p22;
  732.  
  733.   if ((anker1 == NULL) || (anker2 == NULL))
  734.     return (0);
  735.  
  736.   p11 = anker1;
  737.   p12 = p11;
  738.   p21 = anker2;
  739.   p22 = p21;
  740.  
  741.   do
  742.     {
  743.       p11 = p12;
  744.       p21 = p22;
  745.       p12 = (*p11).next;
  746.       p22 = (*p21).next;
  747.  
  748.       if ((p12 != NULL) && (p22 != NULL))
  749.     {
  750.       fprintf (fp, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", (*p11).x, (*p11).y, (*p11).z, (*p12).x, (*p12).y, (*p12).z, (*p21).x, (*p21).y, (*p21).z);
  751.  
  752.       fprintf (fp, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", (*p21).x, (*p21).y, (*p21).z, (*p12).x, (*p12).y, (*p12).z, (*p22).x, (*p22).y, (*p22).z);
  753.     }
  754.     }
  755.   while ((p12 != NULL) && (p22 != NULL));
  756.  
  757.   return (0);
  758. }                /* writerawtriangles */
  759.  
  760. /********************************************/
  761. /*calcg:                                    */
  762. /********************************************/
  763. double
  764. calcg (double O, double N)
  765. {
  766.   if (N == 0)
  767.     return (0);
  768.   else
  769.     return ((2 * pi) / N * (O * N / (2 * pi) - round (O * N / (2 * pi))));
  770.  
  771. }                /* calcg */
  772.  
  773.  
  774. /********************************************/
  775. /*calck:                                    */
  776. /********************************************/
  777. double
  778. calck (struct ShellyArguments *ShellyArgs, double S, double O)
  779. {
  780.   static double N, N2, N3, L, L2, L3, W1, W2, W12, W13, W22, W23, P, P2,
  781.     P3, Off2, Off3;
  782.   double k = 0, g;
  783.   static int called = 0;
  784.  
  785.  
  786.  
  787.   if (called == 0)
  788.     {
  789.  
  790.       N = (*ShellyArgs).N;
  791.       W1 = (*ShellyArgs).W1 * pi / 180;
  792.       W2 = (*ShellyArgs).W2 * pi / 180;
  793.       P = (*ShellyArgs).P * pi / 180;
  794.       L = (*ShellyArgs).L;
  795.  
  796.       N2 = (*ShellyArgs).N2;
  797.       W12 = (*ShellyArgs).W12 * pi / 180;
  798.       W22 = (*ShellyArgs).W22 * pi / 180;
  799.       P2 = (*ShellyArgs).P2 * pi / 180;
  800.       L2 = (*ShellyArgs).L2;
  801.  
  802.       N3 = (*ShellyArgs).N3;
  803.       W13 = (*ShellyArgs).W13 * pi / 180;
  804.       W23 = (*ShellyArgs).W23 * pi / 180;
  805.       P3 = (*ShellyArgs).P3 * pi / 180;
  806.       L3 = (*ShellyArgs).L3;
  807.  
  808.       Off2 = (*ShellyArgs).Off2 * pi / 180;
  809.       Off3 = (*ShellyArgs).Off3 * pi / 180;
  810.  
  811.     }
  812.  
  813.  
  814.   g = calcg (O, N);
  815.   if (N != 0)
  816.     k = L * exp (-(2 * (S - P) / W1) * (2 * (S - P) / W1)) * exp (-(2 * g / W2) * (2 * g / W2));
  817.  
  818.   g = calcg (O + Off2, N2);
  819.   if (N2 != 0)
  820.     k = k + (L2 * exp (-(2 * (S - P2) / W12) * (2 * (S - P2) / W12)) * exp (-(2 * g / W22) * (2 * g / W22)));
  821.  
  822.   g = calcg (O + Off3, N3);
  823.   if (N3 != 0)
  824.     k = k + (L3 * exp (-(2 * (S - P3) / W13) * (2 * (S - P3) / W13)) * exp (-(2 * g / W23) * (2 * g / W23)));
  825.  
  826.   called = 1;
  827.  
  828.   return (k);
  829. }                /* calck */
  830.  
  831.  
  832. /********************************************/
  833. /*innodule:                                 */
  834. /********************************************/
  835. double
  836. innodule (struct ShellyArguments *ShellyArgs, double sc, double O)
  837. {
  838.   static double N, N2, N3, L, L2, L3, W2, W22, W23, Off2, Off3;
  839.  
  840.   double k1 = 0, k2 = 0, g;
  841.   static int called = 0;
  842.  
  843.  
  844.   if (called == 0)
  845.     {
  846.  
  847.       N = (*ShellyArgs).N;
  848.       W2 = (*ShellyArgs).W2 * pi / 180;
  849.       L = (*ShellyArgs).L;
  850.       N2 = (*ShellyArgs).N2;
  851.       W22 = (*ShellyArgs).W22 * pi / 180;
  852.       L2 = (*ShellyArgs).L2;
  853.       N3 = (*ShellyArgs).N3;
  854.       W23 = (*ShellyArgs).W23 * pi / 180;
  855.       L3 = (*ShellyArgs).L3;
  856.       Off2 = (*ShellyArgs).Off2 * pi / 180;
  857.       Off3 = (*ShellyArgs).Off3 * pi / 180;
  858.  
  859.       called = 1;
  860.     }
  861.  
  862.   g = calcg (O, N);
  863.   if (N != 0)
  864.     k1 = L * exp (-(2 * g / W2) * (2 * g / W2));
  865.   g = calcg (O + Off2, N2);
  866.   if (N2 != 0)
  867.     k1 = k1 + (L2 * exp (-(2 * g / W22) * (2 * g / W22)));
  868.   g = calcg (O + Off3, N3);
  869.   if (N3 != 0)
  870.     k1 = k1 + (L3 * exp (-(2 * g / W23) * (2 * g / W23)));
  871.  
  872.   g = calcg (O + sc, N);
  873.   if (N != 0)
  874.     k2 = L * exp (-(2 * g / W2) * (2 * g / W2));
  875.   g = calcg (O + Off2 + sc, N2);
  876.   if (N2 != 0)
  877.     k2 = k2 + (L2 * exp (-(2 * g / W22) * (2 * g / W22)));
  878.   g = calcg (O + Off3 + sc, N3);
  879.   if (N3 != 0)
  880.     k2 = k2 + (L3 * exp (-(2 * g / W23) * (2 * g / W23)));
  881.  
  882.  
  883.   return (fabs (k1) - fabs (k2));
  884.  
  885. }                /* innodule */
  886.  
  887.  
  888. /********************************************/
  889. /*calccamera:                               */
  890. /********************************************/
  891. void
  892. calccamera (double x, double y, double z)
  893. {
  894.   static double biggest;
  895.  
  896.  
  897.   if ((fabs (x) > fabs (y)) && (fabs (x) > fabs (z)))
  898.     if (fabs (x) > biggest)
  899.       {
  900.     biggest = fabs (x);
  901.     camy = biggest * 1.5;
  902.     camz = biggest * 1.5;
  903.       }
  904.   if ((fabs (y) > fabs (x)) && (fabs (y) > fabs (z)))
  905.     if (fabs (y) > biggest)
  906.       {
  907.     biggest = fabs (y);
  908.     camy = biggest * 1.5;
  909.     camz = biggest * 1.5;
  910.       }
  911.  
  912.   if ((fabs (z) > fabs (y)) && (fabs (z) > fabs (x)))
  913.     if (fabs (z) > biggest)
  914.       {
  915.     biggest = fabs (z);
  916.     camy = biggest * 1.5;
  917.     camz = biggest * 1.5;
  918.       }
  919.  
  920.  
  921.  
  922.  
  923. }                /* calccamera */
  924.  
  925.  
  926. /**********************************************/
  927. /* CalcLine:                                  */
  928. /*                                            */
  929. /**********************************************/
  930. int
  931. calcline (double O, struct ShellyArguments *ShellyArgs, struct punkt **list)
  932. {
  933.   struct punkt *list1 = NULL, *L1p1, *L1p2;
  934.   double x, y, z, R, S, Re, k;
  935.   static double my;
  936.   static double smin, smax, sd, a, b, A, beta, phi, omega, alpha, Scale;
  937.   static int called = 0;
  938.  
  939.   if (called == 0)
  940.     {
  941.       smin = (*ShellyArgs).smin * pi / 180;
  942.       smax = (*ShellyArgs).smax * pi / 180;
  943.       sd = (*ShellyArgs).sd * pi / 180;
  944.  
  945.       alpha = (*ShellyArgs).alpha * pi / 180;
  946.       beta = (*ShellyArgs).beta * pi / 180;
  947.       phi = (*ShellyArgs).phi * pi / 180;
  948.       omega = (*ShellyArgs).omega * pi / 180;
  949.       my = (*ShellyArgs).my * pi / 180;
  950.  
  951.       a = (*ShellyArgs).a;
  952.       b = (*ShellyArgs).b;
  953.       A = (*ShellyArgs).A;
  954.  
  955.       Scale = (*ShellyArgs).Scale;
  956.       called = 1;
  957.     }
  958.   counth = 0;
  959.  
  960.   for (S = smin; (S + sd) < smax; S = S + sd)
  961.     {
  962.       counth++;
  963.       countp++;
  964.  
  965.       Re = pow ((pow (a, -2.0) * (cos (S) * cos (S)) + pow (b, -2.0) * (sin (S) * sin (S))), -0.5);
  966.  
  967.       k = calck (ShellyArgs, S, O);
  968.  
  969.       R = Re + k;
  970.  
  971.       /* alternatively: */
  972.       /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
  973.  
  974.       x = Scale * (A * sin (beta) * cos (O) + R * cos (S + phi) * cos (O + omega) - R * sin (my) * sin (S + phi) * sin (O)) * exp (O * cot (alpha));
  975.       y = Scale * (-1 * A * sin (beta) * sin (O) - R * cos (S + phi) * sin (O + omega) - R * sin (my) * sin (S + phi) * cos (O)) * exp (O * cot (alpha));
  976.       z = Scale * (-1 * A * cos (beta) + R * sin (S + phi) * cos (my)) * exp (O * cot (alpha));
  977.       calccamera (x, y, z);
  978.  
  979.       if ((L1p1 = calloc (1, sizeof (struct punkt))) == NULL)
  980.     {
  981.       fprintf (stderr, "Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
  982.       if (S != smin)
  983.         myfree (list1);
  984.       return (5);
  985.     }            /* if */
  986.       if (S == smin)
  987.     list1 = L1p1;
  988.       else
  989.     (*L1p2).next = L1p1;
  990.       L1p2 = L1p1;
  991.  
  992.       (*L1p1).x = x;
  993.       (*L1p1).y = y;
  994.       (*L1p1).z = z;
  995.  
  996.     }                /* for */
  997.  
  998.   *list = list1;
  999.  
  1000.   return (0);
  1001.  
  1002. }                /* calcline */
  1003.  
  1004.  
  1005. /**********************************************/
  1006. /* CalcNodule:                                */
  1007. /*             SSIA :)                        */
  1008. /**********************************************/
  1009. void
  1010. CalcNodule (struct ShellyArguments *ShellyArgs, char *fout)
  1011. {
  1012.   struct punkt *list1 = NULL, *list2;
  1013.  
  1014.   double sc, t, O, Oold, omin, omax, od, nod;
  1015.   FILE *fptemp, *fp;
  1016.   char *hilf, temp[laenge];
  1017.  
  1018.   omin = (*ShellyArgs).omin * pi / 180;
  1019.   omax = (*ShellyArgs).omax * pi / 180;
  1020.   od = (*ShellyArgs).od * pi / 180;
  1021.   nod = (*ShellyArgs).nod * pi / 180;
  1022.   O = omin;
  1023.   t = (*ShellyArgs).Threshold;
  1024.   sc = (*ShellyArgs).Scan;
  1025.  
  1026.   mycopystr (fout, temp, '\0');
  1027.   hilf = strchr (temp, '\0');
  1028.   if (hilf != NULL)
  1029.     mycopystr (".tmp", hilf, '\0');
  1030.  
  1031.  
  1032.   if ((fptemp = fopen (temp, "w+")) == NULL)
  1033.     {
  1034.       fprintf (stderr, "Could not open outfile: %s!\n", temp);
  1035.       exit (5);
  1036.     }
  1037.  
  1038.   if ((fp = fopen (fout, "w")) == NULL)
  1039.     {
  1040.       fprintf (stderr, "Could not open outfile: %s!\n", fout);
  1041.       exit (5);
  1042.     }
  1043.  
  1044.  
  1045.   fprintf (stderr, "Calculating the Shell:");
  1046.  
  1047.   if (calcline (omin, ShellyArgs, &list1) != 0)
  1048.     exit (5);
  1049.  
  1050.   if ((*ShellyArgs).output == RPL)
  1051.     writerplline (fptemp, list1);
  1052.   if ((*ShellyArgs).output == T3D)
  1053.     writet3dline (fptemp, list1);
  1054.  
  1055.  
  1056.   while (O <= omax)
  1057.     {
  1058.       Oold = O;
  1059.  
  1060.       while ((innodule (ShellyArgs, sc, O) <= t) && (O - Oold < od))
  1061.     O = O + sc;
  1062.  
  1063.       if (calcline (O, ShellyArgs, &list2) != 0)
  1064.     exit (5);
  1065.  
  1066.       fprintf (stderr, ".");
  1067.       fflush (stderr);
  1068.  
  1069.       if ((*ShellyArgs).output == RPL)
  1070.     writerplline (fptemp, list1);
  1071.       if ((*ShellyArgs).output == POV)
  1072.     writepovtriangles (fptemp, list1, list2);
  1073.       if ((*ShellyArgs).output == T3D)
  1074.     writet3dline (fptemp, list1);
  1075.       if ((*ShellyArgs).output == RAW)
  1076.     writerawtriangles (fp, list1, list2);
  1077.  
  1078.       myfree (list1);
  1079.       list1 = list2;
  1080.  
  1081.       if (innodule (ShellyArgs, sc, O) > t)
  1082.     {
  1083.       while ((O <= omax) && (innodule (ShellyArgs, sc, O) > t / 2))
  1084.         {
  1085.  
  1086.           O = O + nod;
  1087.           if (calcline (O, ShellyArgs, &list2) != 0)
  1088.         exit (5);
  1089.  
  1090.           if ((*ShellyArgs).output == RPL)
  1091.         writerplline (fptemp, list1);
  1092.           if ((*ShellyArgs).output == POV)
  1093.         writepovtriangles (fptemp, list1, list2);
  1094.           if ((*ShellyArgs).output == T3D)
  1095.         writet3dline (fptemp, list1);
  1096.           if ((*ShellyArgs).output == RAW)
  1097.         writerawtriangles (fp, list1, list2);
  1098.  
  1099.           fprintf (stderr, ".");
  1100.           fflush (stderr);
  1101.  
  1102.           myfree (list1);
  1103.           list1 = list2;
  1104.  
  1105.         }            /* while */
  1106.     }            /* if */
  1107.     }                /* while */
  1108.  
  1109.  
  1110.   if ((*ShellyArgs).output == POV)
  1111.     writepovheader (fp);
  1112.   if ((*ShellyArgs).output == T3D)
  1113.     writet3dheader (fp);
  1114.  
  1115.  
  1116.   if ((*ShellyArgs).output == RPL)
  1117.     writerplfinish (fptemp, fp);
  1118.   if ((*ShellyArgs).output == T3D)
  1119.     writet3dfinish (fptemp, fp);
  1120.   if ((*ShellyArgs).output == POV)
  1121.     writepovfinish (fptemp, fp);
  1122.  
  1123.   fprintf (stderr, "\n");
  1124.  
  1125.   myfree (list1);
  1126.  
  1127.  
  1128.   if (fclose (fptemp) != 0)
  1129.     fprintf (stderr, "Error while closing file: %s!\n", temp);
  1130.  
  1131.   if (fclose (fp) != 0)
  1132.     fprintf (stderr, "Error while closing file: %s!\n", fout);
  1133.   unlink (temp);
  1134. }                /* CalcNodule */
  1135.  
  1136.  
  1137. /**********************************************/
  1138. /* CalcShell:                                 */
  1139. /*             SSIA :)                        */
  1140. /**********************************************/
  1141. void
  1142. CalcShell (struct ShellyArguments *ShellyArgs, char *fout)
  1143. {
  1144.   struct punkt *list1 = NULL, *list2;
  1145.  
  1146.   double O, omin, omax, od;
  1147.   FILE *fptemp, *fp;
  1148.   char temp[laenge], *hilf;
  1149.  
  1150.   omin = (*ShellyArgs).omin * pi / 180;
  1151.   omax = (*ShellyArgs).omax * pi / 180;
  1152.   od = (*ShellyArgs).od * pi / 180;
  1153.  
  1154.  
  1155.   mycopystr (fout, temp, '\0');
  1156.   hilf = strchr (temp, '\0');
  1157.   if (hilf != NULL)
  1158.     mycopystr (".tmp", hilf, '\0');
  1159.  
  1160.   if ((fptemp = fopen (temp, "w+")) == NULL)
  1161.     {
  1162.       fprintf (stderr, "Could not open outfile: %s!\n", temp);
  1163.       exit (5);
  1164.     }
  1165.  
  1166.   if ((fp = fopen (fout, "w")) == NULL)
  1167.     {
  1168.       fprintf (stderr, "Could not open outfile: %s!\n", fout);
  1169.       exit (5);
  1170.     }
  1171.  
  1172.  
  1173.  
  1174.  
  1175.   fprintf (stderr, "Calculating the Shell:");
  1176.  
  1177.   if (calcline (omin, ShellyArgs, &list1) != 0)
  1178.     exit (5);
  1179.  
  1180.  
  1181.   if ((*ShellyArgs).output == RPL)
  1182.     writerplline (fptemp, list1);
  1183.   if ((*ShellyArgs).output == T3D)
  1184.     writet3dline (fptemp, list1);
  1185.  
  1186.   for (O = omin + od; (O + od) < omax; O = O + od)
  1187.     {
  1188.  
  1189.       counth = 0;
  1190.  
  1191.       if (calcline (O, ShellyArgs, &list2) != 0)
  1192.     exit (5);
  1193.  
  1194.       fprintf (stderr, ".");
  1195.       fflush (stderr);
  1196.  
  1197.  
  1198.       if ((*ShellyArgs).output == RPL)
  1199.     writerplline (fptemp, list1);
  1200.       if ((*ShellyArgs).output == POV)
  1201.     writepovtriangles (fptemp, list1, list2);
  1202.       if ((*ShellyArgs).output == T3D)
  1203.     writet3dline (fptemp, list1);
  1204.       if ((*ShellyArgs).output == RAW)
  1205.     writerawtriangles (fp, list1, list2);
  1206.  
  1207.  
  1208.       myfree (list1);
  1209.       list1 = list2;
  1210.  
  1211.     }                /* for */
  1212.  
  1213.   if ((*ShellyArgs).output == POV)
  1214.     writepovheader (fp);
  1215.   if ((*ShellyArgs).output == T3D)
  1216.     writet3dheader (fp);
  1217.  
  1218.  
  1219.   if ((*ShellyArgs).output == RPL)
  1220.     writerplfinish (fptemp, fp);
  1221.   if ((*ShellyArgs).output == T3D)
  1222.     writet3dfinish (fptemp, fp);
  1223.   if ((*ShellyArgs).output == POV)
  1224.     writepovfinish (fptemp, fp);
  1225.  
  1226.   fprintf (stderr, "\n");
  1227.  
  1228.   myfree (list1);
  1229.  
  1230.  
  1231.   if (fclose (fptemp) != 0)
  1232.     fprintf (stderr, "Error while closing file: %s!\n", temp);
  1233.  
  1234.   if (fclose (fp) != 0)
  1235.     fprintf (stderr, "Error while closing file: %s!\n", fout);
  1236.   unlink (temp);
  1237. }                /* CalcShell */
  1238.  
  1239.  
  1240. /**********************************************/
  1241. /* RenderPov:                                 */
  1242. /*           invoke pov for rendering         */
  1243. /**********************************************/
  1244. void
  1245. RenderPov (struct ShellyArguments *ShellyArgs, char *fout)
  1246. {
  1247.   char call[laenge];
  1248.  
  1249.   printf ("Rendering...\n");
  1250.  
  1251.   mycopystr ("pov ", call, '\0');
  1252.   mycopystr ((*ShellyArgs).povargs, &call[4], '\0');
  1253.   strcat (call, " +i");
  1254.   strcat (call, fout);
  1255.   system (call);
  1256.  
  1257.  
  1258. }                /* RenderPov */
  1259.  
  1260.  
  1261. /********************************************/
  1262. /*main:                                     */
  1263. /********************************************/
  1264. int
  1265. main (int ac, char **av)
  1266. {
  1267.   struct ShellyArguments ShellyArgs;
  1268.  
  1269.   fprintf (stderr, "ShellyV1.4, the ShellShapeGenerator by RANDi\n");
  1270.  
  1271.   if (ac != 3)
  1272.     {
  1273.       fprintf (stderr, "USAGE:\n\n");
  1274.       fprintf (stderr, "   'shelly infilename outfilename'\n\n");
  1275.       exit (1);
  1276.     }                /* if */
  1277.  
  1278.   ReadInfile (&ShellyArgs, av[1]);
  1279.  
  1280.   if (ShellyArgs.mode == NORMAL)
  1281.     CalcShell (&ShellyArgs, av[2]);
  1282.   if (ShellyArgs.mode == NODULE)
  1283.     CalcNodule (&ShellyArgs, av[2]);
  1284.  
  1285.   if (ShellyArgs.Render == YES)
  1286.     if (ShellyArgs.output != POV)
  1287.       fprintf (stderr, "Rendering is only available for POV-output!\n(Ever tried to feed a RPL-Macro into POV? ;))\n");
  1288.     else
  1289.       RenderPov (&ShellyArgs, av[2]);
  1290.  
  1291.   exit (0);
  1292. }
  1293.